#include <iostream>
#include <pthread.h>
#include <vector>
#include <queue>
#include "thread.hpp"
using namespace std;

template<class T>
class ThreadPool
{

public:
    ThreadPool(int num = 5)
    :_num(num),
     _running(false),
     _wait_num(0)
     {
        //初始化互斥锁和条件变量
        pthread_mutex_init(&_mutex,nullptr);
        pthread_cond_init(&_cond,nullptr);
     }
     void addTask(T task)
     {
        pthread_mutex_lock(&_mutex);
        if(_running)
        {
            _tasks.push(task);
            //是否存在正在等待的线程
            if(_wait_num>0)
            {
                //唤醒线程
                pthread_cond_signal(&_cond);
            }

        }
        //解锁
        pthread_mutex_unlock(&_mutex);
     }
     void handlerThread(string name)
     {
        while(true)
        {
            pthread_mutex_lock(&_mutex);
            while(_tasks.empty()&&_running)
            {
                _wait_num+=1;
                pthread_cond_wait(&_cond,&_mutex);
                _wait_num-=1;
            }
            if(!_running&&_tasks.empty())
            {
                pthread_mutex_unlock(&_mutex);
                break;
            }

            auto task = _tasks.front();
            _tasks.pop();
            pthread_mutex_unlock(&_mutex);

            task();
        }
     } 
     void init_thread()
     {
        
        auto func = bind(&ThreadPool::handlerThread,this,placeholders::_1);
        for(int i = 0;i<_num;++i)
        {
            string name = "thread-"+to_string(i);
            _threads.emplace_back(func,name,name);
        }
     }
     void start_all()
     {
        _running = true;
        for(auto&thread:_threads)
        {
            if(!thread.start())
            {
                cout<<thread.name()<<"创建失败"<<endl;
            }
        }
     }

     void all_stop()
     {
        pthread_mutex_lock(&_mutex);
        _running = false;
        pthread_cond_broadcast(&_cond);
        pthread_mutex_unlock(&_mutex);

     }

     void all_join()
     {
        for(auto&thread:_threads)
        {
            thread.join();
        }
     }

     ~ThreadPool()
     {
        //销毁互斥锁和条件变量
        pthread_mutex_destroy(&_mutex);
        pthread_cond_destroy(&_cond);
     }


private:
    int _num;
    vector<Thread<string>> _threads;
    queue<T> _tasks;
    int _wait_num;
    bool _running;

    pthread_mutex_t _mutex;
    pthread_cond_t _cond;
};